﻿using System;
using System.Collections;
using System.Data;
using CapaDatos;
using System.Collections.Generic;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;

namespace CapaNegocio
{
    public class Admin
    {
        public Admin()
        {
        }

        #region METODOS_GENERICOS

        //BUSCAR tanto producto y premio. Busca por el campo "descripcion".
        //devuelve la cantidad entera de tuplas resultantes de hacer 
        //una consulta en la tabla especificada y con la condición de filtro especificada
        //los nombres de las tablas los pasa siempre a minusculas, ya que están creadas en minusculas
        public int buscarEnBD(string unaTabla, string unaDesc)
        {
            string query1 = "SELECT * FROM "+ unaTabla +" WHERE descripcion= '" + unaDesc + "'; ";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query1);

            return ds.Tables[0].Rows.Count;
        }

        public int buscarEnBD(string unaTabla, int dni)
        {
            string query = "SELECT * FROM " + unaTabla + " WHERE dni= " + dni+";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            return ds.Tables[0].Rows.Count;
        }

        //LISTAR GENERICO
        public DataTable listar(string unaTabla)
        {
            string query = "SELECT * FROM " +unaTabla+ ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            DataTable dt = new DataTable();
            dt = ds.Tables[0];
            return dt;
        }
       
        #endregion

        #region Premios
        //----------------------------------------------------------------
        //                  ADMINISTRACION PREMIOS
        //----------------------------------------------------------------

        //BUSCAR PREMIO POR NROPREMIO
        public DataSet buscarEnBDNroPremio(int unNroPremio)
        {
            string query = "SELECT * FROM premio WHERE nroPremio= " + unNroPremio + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            return ds;
        }

        //ALTA DE PREMIO
        public Boolean altaPremio(string unaDesc, int unosPuntos, int unStock)
        {
            string tabla = "premio";
            if (buscarEnBD(tabla, unaDesc) == 0)
            {
                //no existe el premio
                Premio premio = new Premio(unaDesc, unosPuntos, unStock);
                ArrayList datoPremio = Mapeo.DarPremio_Relacional(premio);
                string query2 = "INSERT INTO premio(descripcion, puntosNecesarios,stock) Values('" + datoPremio[0].ToString() + "'," + int.Parse(datoPremio[1].ToString()) + "," + int.Parse(datoPremio[2].ToString()) + ") ;";
                Datos.ConsultarEx(query2);
                return true;
            }
            else
                return false; //el premio existe
        }

        //BAJA DE PREMIO
        public Boolean bajaPremio(int nroPre)
        {
            string query = "DELETE FROM premio WHERE nroPremio=" + nroPre + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            //no se me ocurre como verificar si la operación fue correcta o no para enviarle la respuesta a la "capa usuario"
            return true;
        }

        //MODIFICAR PREMIO PUNTOS
        public Boolean modificarPremioPuntos(int unNro, int unosPuntos)
        {
            string query = "UPDATE premio SET puntosNecesarios=" + unosPuntos + " WHERE nroPremio=" + unNro + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            //no se me ocurre como verificar si la operacion fue correcta o no para enviarle la respuesta a la "capa usuario"
            return true;
        }

        //MODIFICAR PREMIO STOCK
        public Boolean modificarPremioStock(int unNro, int unStock)
        {
            string query = "UPDATE premio SET stock=" + unStock + " WHERE nroPremio=" + unNro + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            //no se me ocurre como verificar si la operacion fue correcta o no para enviarle la respuesta a la "capa usuario"
            return true;
        }
        //LISTAR PREMIOS SEGUN PUNTAJE DEL CLIENTE Y EL STOCK DISPONIBLE
        public DataTable listarPremios(int puntos)
        {
            string query = "SELECT * FROM premio WHERE stock>0 AND puntosNecesarios<= " + puntos + " ;";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            DataTable dt=new DataTable();
            dt = ds.Tables[0];
            return dt;

        }
        //ACTUALIZA EL STOCK DE UN PREMIO
        public Boolean actualizarstockPremio(int nroPremio, int puntos)
        {
            string query = "UPDATE premio SET stock= " + puntos + " WHERE nroPremio= " + nroPremio + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            return true;
        }

        #endregion

        #region Producto
        //----------------------------------------------------------------
        //                  ADMINISTRACION PRODUCTOS
        //----------------------------------------------------------------

        //ALTA DE PRODUCTO
        public Boolean altaProducto(string unaDesc, decimal unPrecio, int unStock)
        {
            string tabla = "producto";
            if (buscarEnBD(tabla, unaDesc) == 0)
            {
                //no existe el producto
                Producto producto = new Producto(unaDesc, unPrecio, unStock);
                //ArrayList datoProducto = Mapeo.DarProducto_Relacional(producto);

                string query2 = "INSERT INTO producto(descripcion, precio, stock) Values('" + unaDesc + "'," + unPrecio + "," + unStock + ") ;";
                Datos.ConsultarEx(query2);
                return true;
            }
            else
                return false;
        }

        //BAJA PRODUCTO
        public Boolean bajaProducto(int nroProd)
        {
            string query = "DELETE FROM producto WHERE nroProducto=" + nroProd + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            //no se me ocurre como verificar si la operación fue correcta o no para enviarle la respuesta a la "capa usuario"
            if (ds.Tables.Count == 0)
                return true;
            else
                return false;
        }

        //MODIFICAR PRECIO DE UN PRODUCTO
        public Boolean modificarProductoPrecio(int unNro, decimal unPrecio)
        {
            string query = "UPDATE producto SET precio=" + unPrecio + " WHERE nroProducto=" + unNro + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            //no se me ocurre como verificar si la operacion fue correcta o no para enviarle la respuesta a la "capa usuario"
            return true;
        }

        //MODIFICAR STOCK DE UN PRODUCTO
        public Boolean modificarProductoStock(int unNro, int unStock)
        {
            string query = "UPDATE producto SET stock=" + unStock + " WHERE nroProducto=" + unNro + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            //no se me ocurre como verificar si la operacion fue correcta o no para enviarle la respuesta a la "capa usuario"
            return true;
        }
        public DataTable buscarProducto(string Tabla, string Desc)
        {
            string query1 = "SELECT * FROM " + Tabla + " WHERE descripcion= '" + Desc + "'; ";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query1);
            DataTable dt = new DataTable();
            dt = ds.Tables[0];
            return dt;

        }
        public DataTable buscarProduc( int nro)
        {
            string query1 = "SELECT * FROM producto WHERE nroProducto= " + nro + "; ";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query1);
            DataTable dt = new DataTable();
            dt = ds.Tables[0];
            return dt;

        }
        //listar productos exceptuando algunos--es para la solucion de eliminar productos de la linea de compra--
        public DataTable listarProductos(ArrayList nroProductos)
        {
            int i;
            string query = "SELECT * FROM  producto WHERE nroProducto<> "+nroProductos[0]+" ";
            for(i=1;i<nroProductos.Count;i++)
            {
                //concateno 
                string query2 =  " AND nroProducto<> "+nroProductos[i];
                query += query2;
            }
            //le agrego el ";" al final de la consulta
            query += ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            DataTable dt = new DataTable();
            dt = ds.Tables[0];
            return dt;
            
        }
        #endregion

        #region Clientes;

        //----------------------------------------------------------------
        //                  ADMINISTRACION CLIENTES
        //----------------------------------------------------------------

        //BUSCA EN LA BD POR NROCLIENTE y devuelve una tabla con la fila buscada.
        public DataSet buscarEnBDNroCliente(string unaTabla, int unNroCliente)
        {
            string query = "SELECT * FROM " + unaTabla + " WHERE nroCliente= " + unNroCliente + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            return ds; 
        }

        // ALTA CLIENTE COMUN
        public Boolean altaClienteComun(int dni, string email, DateTime fechaAlta, string nombre, int nroCelular)
        {
            
            string tabla="cliente";
            if (buscarEnBD(tabla, dni) == 0)
            // el cliente no existe entonces lo agrego a la bd
            {
               
                ClienteComun cli=new ClienteComun(dni,email,fechaAlta,nombre,nroCelular);//no me convence mucho esta implementacion ya que creo el objeto solo para obtener los puntosOorgados para la compra
                int puntosOtorgados=cli.darPuntosOtorgados();
                string query = "INSERT INTO cliente(dni,email,fechaAlta,nombre,nroCelular,puntosOtorgados,tipoCliente) values(" + dni + ",'" + email + "','" + fechaAlta.ToShortDateString() + "','" + nombre + "'," + nroCelular + "," + puntosOtorgados + ",'comun');";
                Datos.ConsultarEx(query);
                return true;
            }
            else
                return false;

        }
        //ALTA CLIENTE ESPECIAL
        public Boolean altaClienteEspecial(int dni, string email, DateTime fechaAlta, string nombre, int nroCel)
        {

            string tabla = "cliente";
            if (buscarEnBD(tabla, dni) == 0)
            // el cliente no existe entonces lo agrego a la bd
            {
                ClienteEspecial cli = new ClienteEspecial(dni, email, fechaAlta, nombre, nroCel);//no me convence mucho esta implementacion ya que creo el objeto solo para obtener los puntosOorgados para la compra
                int puntosOtorgados = cli.darPuntosOtorgados();
                string query = "INSERT INTO cliente(dni,email,fechaAlta,nombre,nroCelular,puntosOtorgados,tipoCliente) values(" + dni + ",'" + email + "','" + fechaAlta.ToShortDateString() + "','" + nombre + "'," + nroCel + "," + puntosOtorgados + ",'especial');";
                Datos.ConsultarEx(query);
                return true;
            }
            else
                return false;

        }
        //BAJA DE CLIENTE
        public Boolean bajaCliente(int nroDni)
        {
            string query = "DELETE FROM cliente WHERE dni= " + nroDni + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            
           
                return true;
        }
        //MODIFICAR DATOS DEL CLIENTE
        public Boolean modificarCliente(int dni,string email, string nroCelular)
        {
            string query1 = "UPDATE cliente SET email= '" + email + "',nroCelular= '" + nroCelular + "' WHERE dni= " + dni + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query1);
            return true;
        }
        //MODIFICAR PUNTOS OTORGADOS
        public Boolean modificarPuntosCompra(int puntosOtorgados,int puntos)
        {
            string query = "UPDATE cliente SET puntosOtorgados= " + puntos + " WHERE puntosOtorgados= " + puntosOtorgados + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            return true;
        }
        // ACTUALIZAR PUNTOS DEL CLIENTE
        public Boolean actualizarPuntos(int nroCliente,int puntos)
        {
            string query = "UPDATE cliente SET puntosAcumulados= " + puntos + " WHERE nroCliente= " + nroCliente + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            return true;

        }
         

        #endregion;

        #region retiroPremio;
        //----------------------------------------------------------------
        //                  ADMINISTRACION DE RETIRO DE PREMIOS
        //----------------------------------------------------------------

        //IMPORTANTE, MODIFIQUE NRODNI POR NROCLIENTE
        public Boolean altaRetiroPremio(int nroCliente,int nroPremio,int puntosClienteActualizados,int stockAactualizado,DateTime fecha)
        {

            if ((actualizarPuntos(nroCliente, puntosClienteActualizados) == true) && (actualizarstockPremio(nroPremio, stockAactualizado) == true) )//actualizo los puntos del cliente y el stock del premio 
            {
                string query = "INSERT INTO retirodepremio(nroPremio,nroCliente,fechaRetiro) values (" + nroPremio + "," + nroCliente + ",'" + fecha.ToShortDateString() + "');";
                DataSet ds = new DataSet();
                ds = Datos.ConsultarEx(query);
                return true;
            }
            else
                return false;

        }

        #endregion;
        #region compra;
        //----------------------------------------------------------------
        //                  ADMINISTRACION DE COMPRAS
        //----------------------------------------------------------------
        // ALTA DE COMPRA
        public Boolean altaCompra(int nroCliente,List<LineaCompra>lista,DateTime fechaCompra,decimal importe)
        {
            int nroCompra;
            if (actualizarPuntajeCliente(nroCliente, importe) == true && actualizarStockProducto(lista) == true)
            {
                nroCompra = darNroCompra();


                string query = "INSERT INTO compra(fechaCompra,nroCliente,total)values('" + fechaCompra.ToShortDateString() + "'," + nroCliente + ",'" + importe + "');";
                DataSet ds = new DataSet();
                ds = Datos.ConsultarEx(query);
                altaLineaCompra(nroCompra, lista);
                
            }
            return true;
        }
        //INSERTA EN LA BD cada fila de linea de compra referida a una compra
        private Boolean altaLineaCompra(int nroCompra,List<LineaCompra>linea)
        {
            int i=0;
            string query=" ";
            for(i=0;i<linea.Count;i++)
            {
                query="INSERT INTO lineadecompra(nroCompra,cantidad,nroProducto) values("+nroCompra+","+linea[i].Cantidad+","+linea[i].Producto+");";
                DataSet ds=new DataSet();
                ds=Datos.ConsultarEx(query);

            }
            return true;
        }
        //actualizar puntaje del cliente luego de la compra
        private Boolean actualizarPuntajeCliente(int nroCliente, decimal importe)
        {
            Cliente cliente;
            DataSet ds = new DataSet();
            int puntos;
            //1°-busco el cliente en la bd y convierto la tupla en objeto de tipo Cliente
            ds = this.buscarEnBDNroCliente("cliente", nroCliente);
            ArrayList datos=new ArrayList();
            datos.Add(ds.Tables[0].Rows[0].ItemArray[0]);//dni
            datos.Add(ds.Tables[0].Rows[0].ItemArray[1]);//email
            datos.Add(ds.Tables[0].Rows[0].ItemArray[2]);//fechaAlta
            datos.Add(ds.Tables[0].Rows[0].ItemArray[3]);//nombre
            datos.Add(ds.Tables[0].Rows[0].ItemArray[4]);//nroCliente
            datos.Add(ds.Tables[0].Rows[0].ItemArray[5]);//puntosAcumulados
            datos.Add(ds.Tables[0].Rows[0].ItemArray[6]);//nroCelular
            datos.Add(ds.Tables[0].Rows[0].ItemArray[8]);//tipoCliente
            cliente=Mapeo.DarCliente_Objeto(datos);
            //2°- calculo puntaje y actualizo puntaje
            puntos = cliente.PuntosAcumulados + cliente.calcularImporte(importe);//me da el puntaje final a actualizar
            actualizarPuntos(cliente.NroCliente, puntos);
            return true;
        }
        //actualizo el stock de los productos
        public Boolean actualizarStockProducto(List<LineaCompra> linea)
        {
            int i;
            int nuevoStock;
            for (i = 0; i < linea.Count; i++)
            {
                DataTable dt=new DataTable();
                //busco en la bd el stock el stock que tiene actualmente
                //y lo resto con la cantidad de la linea de compra
                dt=buscarProducto("producto", linea[i].getProducto().Descripcion);
                nuevoStock =Convert.ToInt32( dt.Rows[0].ItemArray[3]) - linea[i].Cantidad;
                //luego actualizo en la bd el stock
               modificarProductoStock(Convert.ToInt32( dt.Rows[0].ItemArray[0]), nuevoStock);

            }
            return true;
        }
        public DataTable buscarCompra(int nroCompra)
        {
            string query = "SELECT * FROM compra= " + nroCompra + "WHERE nroCompra= " + nroCompra + ";";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            DataTable dt = new DataTable();
            dt = ds.Tables[0];
            return dt;
        }
        public int darNroCompra()
        {
            string query="SELECT MAX(nroCompra)FROM compra";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            return Convert.ToInt32(ds.Tables[0].Rows[0].ItemArray[0] is DBNull ? 0 : ds.Tables[0].Rows[0].ItemArray[0]) + 1;//linea de codigo que me controla si una celda devuelve null
                
           

        }

        #endregion:



        #region Web

        //BUSCAR  USUARIO EN BD
        public DataSet buscarEnBDUsuario(string unUsuario, string unPass)
        {
            string query = "SELECT * FROM cuenta WHERE usuario= '" + unUsuario + "' AND contrasenia= '"+ unPass +"';";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            return ds;
        }

        ////LISTA LA CANTIDAD DE CLIENTES QUE TIENEN PUNTOS ENTRE EL RANGO 0 A 100 INCLUSIVE DE PUNTOS ACUMULADOS
        public DataSet listarClientesRango1()
        {
            string query = "SELECT COUNT(*) AS TOTAL_DE_CLIENTES  FROM cliente WHERE puntosAcumulados<=100;";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            return ds;
        }

        ////LISTA LA CANTIDAD DE CLIENTES QUE TIENEN PUNTOS ENTRE EL RANGO 101 y 1000 INCLUSIVE DE PUNTOS ACUMULADOS
        public DataSet listarClientesRango2()
        {
            string query = "SELECT COUNT(*) AS TOTAL_DE_CLIENTES  FROM cliente WHERE puntosAcumulados>100 AND puntosAcumulados<=1000 ;";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            return ds;
        }

        ////LISTA LA CANTIDAD DE CLIENTES QUE TIENEN MAS DE 1000 PUNTOS ACUMULADOS
        public DataSet listarClientesRango3()
        {
            string query = "SELECT COUNT(*) AS TOTAL_DE_CLIENTES  FROM cliente WHERE puntosAcumulados>1000 ;";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            return ds;
        }

        ////LISTA LA CANTIDAD DE CLIENTES QUE ELIGIERON CADA PREMIO
        public DataSet listarClientesPorPremio()
        {
            string query = "SELECT nroPremio,  COUNT(*) AS CLIENTES_QUE_SELECCIONARON FROM retirodepremio GROUP BY nroPremio ;";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            return ds;
        }

        //LISTAR EMAILS DE CLIENTES
        public DataTable listarEmails()
        {
            string query = "SELECT email FROM cliente;";
            DataSet ds = new DataSet();
            ds = Datos.ConsultarEx(query);
            DataTable dt = new DataTable();
            dt = ds.Tables[0];
            return dt;
        }

        //ENVIO DE EMAILS
        public void envioDeEmail(string unMensaje)
        {
            //ESTE EVENTO DEBE RECORRER LA TABLA DE CLIENTES Y POR CADA UNO EJECUTARSE
            DataTable dt = new DataTable();
            dt = listarEmails();


            System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
            
            msg.To.Add("jfacundonervo@gmail.com");
            msg.From = new MailAddress("centralpetshops.a@gmail.com", "Pet Shop S.A", System.Text.Encoding.UTF8);
            msg.Subject = "Prueba de correo a GMail";
            msg.SubjectEncoding = System.Text.Encoding.UTF8;
            msg.Body = unMensaje;
            msg.BodyEncoding = System.Text.Encoding.UTF8;
            msg.IsBodyHtml = false;

            //Aquí es donde se hace lo especial
            SmtpClient client = new SmtpClient();
            client.Credentials = new System.Net.NetworkCredential("centralpetshops.a@gmail.com", "petshop123456");
            client.Port = 587;
            client.Host = "smtp.gmail.com";
            client.EnableSsl = true; //Esto es para que vaya a través de SSL que es obligatorio con GMail
            try
            {
                client.Send(msg);
            }
            catch (SmtpException ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }


        #endregion

    }//fin clase
}//fin namespace
